package com.qqt.csr.archive.service;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qqt.csr.archive.entity.reader.CsrImAccount;
import com.qqt.csr.archive.entity.reader.item.AccountExtItem;
import com.qqt.csr.archive.mapper.CsrImAccountMapper;
import com.qqt.csr.common.utils.CacheKeyUtil;
import com.qqt.csr.common.utils.RedissonLockUtil;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @Author: yang hao
 * @Date: 2024/11/20 9:08
 * @Description: 人工客服 账户信息
 **/
@Slf4j
@Service
public class CsrImAccountService extends ServiceImpl<CsrImAccountMapper, CsrImAccount> {

    @Autowired
    private RedissonLockUtil redissonLockUtil;
    @Autowired
    private RedissonClient redissonClient;

    /**
     * 根据账户id集查询账户信息集
     * @param ids {@link List<String>} 账户id集
     * @return {@link List<CsrImAccount>} 账户信息集
     */
    public List<CsrImAccount> getByIds(List<String> ids) {
        if (ids == null || ids.isEmpty()) {
            return Collections.emptyList();
        }
        List<CsrImAccount> accounts = baseMapper.selectBatchIds(ids);
        accounts.forEach(account -> {
            String extJson = account.getExtJson();
            if (Objects.nonNull(extJson)) {
                AccountExtItem extItem = JSONUtil.toBean(extJson, AccountExtItem.class);
                account.setExt(extItem);
            }
        });
        return accounts;
    }

    /**
     * 根据账户id查询账户信息
     * @param id {@link String} 账户id
     * @return {@link CsrImAccount} 账户信息
     */
    public CsrImAccount getById(String id) {
        CsrImAccount account = baseMapper.selectById(id);
        if (Objects.nonNull(account)) {
            String extJson = account.getExtJson();
            if (Objects.nonNull(extJson)) {
                AccountExtItem extItem = JSONUtil.toBean(extJson, AccountExtItem.class);
                account.setExt(extItem);
            }
        }
        return account;
    }

    /**
     * 根据用户id查询账户数量
     * @param userId {@link String} 用户id
     * @return {@link Long} 账户数量
     */
    public Long getByUserId(String userId) {
        LambdaQueryWrapper<CsrImAccount> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CsrImAccount::getAccountUserId, userId);
        return baseMapper.selectCount(wrapper);
    }

    /**
     * 根据用户id查询账户
     * @param accountUserId {@link String} 用户id
     * @return {@link CsrImAccount} 账户
     */
    public CsrImAccount getByAccountUserId(String accountUserId) {
        LambdaQueryWrapper<CsrImAccount> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(CsrImAccount::getAccountUserId, accountUserId);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * @param userId {@link String} 账户用户id
     * @param type {@link Integer} 用户类型 0：用户；1：客服；2：机器人
     * @param channelId {@link String} 渠道id
     * @return {@link Boolean}
     */
    public CsrImAccount getAccountByUserId(String userId, Integer type, String channelId) {
        LambdaQueryWrapper<CsrImAccount> wrapper = new LambdaQueryWrapper<>();
        String value;
        if (type == 0) {
            value = String.format("CSR%s-%s", channelId, userId);
        } else if (type == 2) {
            value = String.format("ROBOT%s", userId);
        } else {
            return null;
        }
        wrapper.eq(CsrImAccount::getAccountUserId, value);
        return baseMapper.selectOne(wrapper);
    }

    /**
     * 保存账户 不存在则新增
     * @param account {@link CsrImAccount} 账户信息
     */
    public void saveIfNotExist(CsrImAccount account) {
        log.info("保存账户, Thread:{}, account:{}", Thread.currentThread(), JSONUtil.toJsonStr(account));
        String lockKey = String.format(CacheKeyUtil.IM.CREATE_ACCOUNT_LOCK, account.getAccountUserId());
        redissonLockUtil.distributedLock(() -> {
            CsrImAccount origAccount = getByAccountUserId(account.getAccountUserId());
            if (origAccount == null) {
                save(account);
            }
            return account;
        }, lockKey, 0, 30, TimeUnit.SECONDS);
    }

    /**
     * 批量保存账户
     * @param accounts {@link List<CsrImAccount>} 账户信息集
     */
    public void saveBatchIfNotExist(List<CsrImAccount> accounts) {
        if (accounts == null || accounts.isEmpty()) {
            return;
        }
        accounts.forEach(this::saveIfNotExist);
    }

}
